//#include "lwip/opt.h"


#include <string.h>
#include <time.h>

#include "LPC17xx.h"
#include "lpc17xx_uart.h"
#include "uart.h"
#include "lpc_types.h"

#if LWIP_UDP
#include "snmpinc.h"
/** SNMP server port */
#ifndef SNMP_PORT
#define SNMP_PORT                   161
#endif

#define SNMP_MSG_SIZE  1400

extern u8_t snmp_buf[1480];
static struct udp_pcb* my_snmp_pcb=NULL;
/** Addresses of servers */
void uart_send(char *str);

void uart_send(char *str)
{

	u32_t i;
	
	i=0;
	while(*(str+i) !='\0'){
		while(UART_CheckBusy(LPC_UART3)==SET);
		UART_Send(LPC_UART3, (uint8_t *)(str+i),1, BLOCKING);
		i++;
	}

}

/** UDP recv callback for the SNMP pcb */
static void my_snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port)
{
//  u16_t i;
  u32_t rem_ip;

  LWIP_UNUSED_ARG(arg);
  LWIP_UNUSED_ARG(pcb);
  LWIP_UNUSED_ARG(addr);
  LWIP_UNUSED_ARG(port);

  /* is the SNMP message too big ? */
  if (p->tot_len > SNMP_MSG_SIZE) {
    LWIP_DEBUGF(DNS_DEBUG, ("my_snmp_recv: pbuf too big\n"));
    /* free pbuf and return */
    goto memerr;
  }
  /* copy SNMP payload inside static buffer for processing */ 
  if (pbuf_copy_partial(p, snmp_buf, p->tot_len, 0) == p->tot_len) 
  {
  	memcpy(&rem_ip,addr,4);
    SNMP_Process_Rcvd_Packet(snmp_buf,p->tot_len,rem_ip,port,0);
  }
memerr:
  /* free pbuf */
  pbuf_free(p);
  return;
}

/** Actually send an SNMP request to a server.
 *
 * @param server_addr resolved IP address of the SNMP server
 */
void my_snmp_send(u8_t rem_ip[4],u16_t port,u8_t *buf,u16_t len)
{
  struct pbuf* p;
  ip_addr_t server_addr;
  ip_addr_t *addr=&server_addr;
  if(len>SNMP_MSG_SIZE)
  {
  	LWIP_DEBUGF(LWIP_DBG_LEVEL_SERIOUS, ("my_snmp_send: too long buf"));
    return;
  }
  p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
  if (p != NULL) 
  {  	
    LWIP_DEBUGF(LWIP_DBG_STATE, ("my_snmp_send: Sending request to server\n"));
    /* initialize request message */
    memcpy(p->payload,buf,len);
    ip4_addr1(addr)=rem_ip[0];
  	ip4_addr2(addr)=rem_ip[1];
  	ip4_addr3(addr)=rem_ip[2];
  	ip4_addr4(addr)=rem_ip[3];
    /* send request */
    udp_sendto(my_snmp_pcb, p, addr, port);
    /* free the pbuf after sending it */
    pbuf_free(p);
  }
  else
  {
    LWIP_DEBUGF(LWIP_DBG_LEVEL_SERIOUS, ("my_snmp_send: Out of memory"));
  }
}
/**
 * Initialize this module.
 * Send out request instantly or after SNMP_STARTUP_DELAY.
 */
void my_snmp_init(void)
{
  if (my_snmp_pcb == NULL) 
  {
    my_snmp_pcb = udp_new();
    LWIP_ASSERT("Failed to allocate udp pcb for SNMP", my_snmp_pcb != NULL);
    if (my_snmp_pcb != NULL) 
    {
      snmpd_init();
     udp_bind(my_snmp_pcb, IP_ADDR_ANY, SNMP_PORT);
	
      udp_recv(my_snmp_pcb, my_snmp_recv, (void *)SNMP_PORT);
	   
    }
  }
}

#endif /* LWIP_UDP */
